<!DOCTYPE html>

<head>
	<title>Gutenberg PR Previewer</title>
	<meta charset="utf-8" />
	<meta name="viewport" content="width=device-width, initial-scale=1" />
	<meta
		property="og:image"
		content="https://playground.wordpress.net/ogimage.png"
	/>
	<meta property="og:title" content="Gutenberg Pull Request preview" />
	<meta
		property="og:description"
		content="Try any gutenberg Pull Request live via WordPress Playground!"
	/>
	<meta
		name="description"
		content="Try any gutenberg Pull Request live via WordPress Playground!"
	/>
	<link
		rel="stylesheet"
		href="https://fonts.googleapis.com/css?family=Noto+Serif:400,700"
	/>
	<link rel="stylesheet" href="./previewer.css" />
	<script
		async
		src="https://www.googletagmanager.com/gtag/js?id=G-SVTNFCP8T7"
	></script>
	<script>
		window.dataLayer = window.dataLayer || [];
		function gtag() {
			dataLayer.push(arguments);
		}
		gtag('js', new Date());
		gtag('config', 'G-SVTNFCP8T7');
	</script>
</head>

<body>
	<div id="main">
		<!--
			Credit for the logo and site design goes to Andrew Duthy
			who originally built and hosted http://gutenberg.run/
		-->
		<svg id="logo" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 150 150">
			<g transform="translate(-311.9 -353.7)">
				<path
					d="M458.6 407c-2.5-1.7-5.9-1-7.6 1.5-9.9 14.9-30.9 15.7-32 15.7h-.5c-25.9 0-35.8 22.1-36.2 23-1.2 2.8.1 6 2.8 7.2.7.3 1.5.5 2.2.5 2.1 0 4.1-1.2 5-3.3.1-.2 6.9-15.4 24.4-16.4v28.3c-.7 6.1-3.6 10.9-8.7 14.5-5.3 3.7-12.4 5.6-21.1 5.6-10.4 0-18.9-3.6-25.2-10.7-6.4-7.1-9.6-17.2-9.6-30.2l.1-31.2c.5-11.5 3.6-20.6 9.5-27.1 6.4-7.1 14.8-10.7 25.2-10.7 8.7 0 15.8 1.9 21.1 5.6 5.3 3.7 8.3 8.8 8.8 15.4v.7c0 3.8 3.1 6.9 6.9 6.9 3.8 0 6.9-3.1 6.9-6.9v-.7c-1-9.9-5.5-17.7-13.6-23.6-8.1-5.9-18.2-8.8-30.4-8.8-14.5 0-26.2 4.8-35.1 14.3-8.4 8.9-12.8 20.6-13.3 35 0 1-.1 2-.1 3l.1 28.1h-.1c0 15.9 4.5 28.6 13.4 38.1s20.6 14.3 35.1 14.3c12.2 0 22.3-2.9 30.4-8.8 7.4-5.4 11.8-12.5 13.3-21.3l.3-31.4c9.1-2.2 21.5-7.2 29.3-19 2-2.5 1.3-5.9-1.3-7.6z"
				/>
			</g>
		</svg>
		<form
			id="create"
			action="https://playground.wordpress.net"
			method="GET"
		>
			<label for="pr-number">Pull request number or URL:</label>
			<div id="createFields">
				<input
					id="pr-number"
					type="text"
					name="pr-number"
					value=""
					required
					autofocus
				/>
				<button id="submit">
					<span class="go">Go</span>
					<span class="verifying">Verifying</span>
				</button>
			</div>
		</form>
		<div id="error"></div>
	</div>

	<div id="links">
		Powered by
		<a href="https://developer.wordpress.org/playground">
			WordPress Playground
		</a>. To build a previewer like this for your repository, check the
		<a
			target="_blank"
			href="https://github.com/WordPress/wordpress-playground/blob/trunk/packages/playground/website/public/gutenberg.html"
			>code on GitHub</a
		>
		and the
		<a
			href="https://wordpress.github.io/wordpress-playground/developers/build-your-first-app/#preview-pull-requests-from-your-repository"
		>
			documentation page</a
		>.
	</div>
	<script>
		/*
		 * This function uses a Playground Blueprint to apply a PR to a WordPress Playground site.
		 *
		 * You could build a similar tool to preview Pull Requests from your own repository!
		 *
		 * Learn more at:
		 *
		 * * https://wordpress.github.io/wordpress-playground/
		 * * https://wordpress.github.io/wordpress-playground/developers/build-your-first-app/#preview-pull-requests-from-your-repository
		 */

		let submitting = false;
		const submitButton = document.getElementById('submit');
		const form = document.getElementById('create');
		const errorDiv = document.getElementById('error');

		// If there's a PR query parameter, call previewPr with its value
		const urlParams = new URLSearchParams(window.location.search);
		const prNumber = urlParams.get('pr');
		if (prNumber) {
			document.getElementById('pr-number').value = prNumber;
			previewPr(prNumber);
		}

		form.addEventListener('submit', async function onSubmit(e) {
			e.preventDefault();
			if (submitting) {
				return;
			}
			let prNumber = document.getElementById('pr-number').value;

			// Extract number from a GitHub URL
			if (
				prNumber
					.toLowerCase()
					.includes('github.com/wordpress/gutenberg/pull')
			) {
				prNumber = prNumber.match(/\/pull\/(\d+)/)[1];
			}

			previewPr(prNumber);
		});

		async function previewPr(prNumber) {
			submitting = true;
			errorDiv.innerText = '';
			submitButton.classList.add('loading');
			submitButton.disabled = true;

			// Verify that the PR exists and that GitHub CI finished building it
			const zipArtifactUrl = `/plugin-proxy.php?org=WordPress&repo=gutenberg&workflow=Build%20Gutenberg%20Plugin%20Zip&artifact=gutenberg-plugin&pr=${prNumber}`;
			// Send the HEAD request to zipArtifactUrl to confirm the PR and the artifact both exist
			const response = await fetch(zipArtifactUrl + '&verify_only=true');
			if (response.status !== 200) {
				errorDiv.innerText = `The PR ${prNumber} does not exist or GitHub CI did not finish building it yet.`;
				submitting = false;
				submitButton.classList.remove('loading');
				submitButton.disabled = false;
				return;
			}

			// Redirect to the Playground site with the Blueprint to download and apply the PR
			const blueprint = {
				landingPage: '/wp-admin/',
				features: {
					networking: true,
				},
				steps: [
					{
						step: 'login',
						username: 'admin',
						password: 'password',
					}
				],
			};
			// If there's a import-site query parameter, pass that to the blueprint
			const urlParams = new URLSearchParams(window.location.search);
			try {
				const importSite = new URL(urlParams.get('import-site'));
				if (importSite) {
					// Add it as the first step in the blueprint
					blueprint.steps.unshift({
						step: 'importWordPressFiles',
						wordPressFilesZip: {
							resource: 'url',
							url: importSite.origin + importSite.pathname,
						},
					});
				}
			} catch {
				console.error('Invalid import-site URL');
			}

			const encoded = JSON.stringify(blueprint);
			window.location =
				'./?gutenberg-pr=' + prNumber + '#' + encodeURI(encoded);
		}
	</script>
</body>
